package com.example.gameapplication.database;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Paint;
import android.media.MediaPlayer;
import android.util.Log;

import com.example.gameapplication.BaseObject;
import com.example.gameapplication.activity.MainActivity;
import com.example.gameapplication.R;
import com.example.gameapplication.bullet.BossSkill;
import com.example.gameapplication.bullet.BossSkillBullet;
import com.example.gameapplication.bullet.Bullet;
import com.example.gameapplication.bullet.BulletBuff;
import com.example.gameapplication.bullet.DoubleBullet;
import com.example.gameapplication.bullet.EnemyBullet;
import com.example.gameapplication.bullet.Skill;
import com.example.gameapplication.bullet.SkillBullet;
import com.example.gameapplication.bullet.WindmillBullet;
import com.example.gameapplication.bullet.WindmillSkill;
import com.example.gameapplication.plant.BigPlane;
import com.example.gameapplication.plant.BossPlane;
import com.example.gameapplication.plant.MiddlePlane;
import com.example.gameapplication.plant.SmallPlane;
import com.example.gameapplication.plant.MainPlane;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class DataUtils {
    static private MainPlane mainPlane;
    static private Bitmap background2;
    static private Bitmap background;
    static private Bitmap playButton;
    static private Bitmap lifeIcon;
    static private Bitmap missile;
    static private float scalex;
    static private float scaley;
    static private float bg_y; // 图片的坐标
    static private float bg_y2;
    static private boolean isPlaying = true;
    static private List<SmallPlane> smallPlanes = new ArrayList<>();
    static private List<MiddlePlane> middlePlanes = new ArrayList<>();
    static private List<BigPlane> bigPlanes = new ArrayList<>();
    static private List<BossPlane> bossPlanes = new ArrayList<>();
    static private ArrayList<BulletBuff> bulletBuffs = new ArrayList<>();
    static private long bulletBuffsTime = 0;
    static private long allScore = 0;
    static private long smallPlaneScore = 100;//击落每台小飞机的分数
    static private long middlePlaneScore = 200;//击落每台中型飞机的分数
    static private long bigPlaneScore = 400;//击落每台中型飞机的分数
    static private long bosPlaneScore = 2000;//击落每台中型飞机的分数
    static private Paint paint;
    static private MediaPlayer mMediaPlayer;
    static private ExecutorService executorService;
    static private long start;
    static private long stop;
    static private int smallPaineMaxLv = 50;//小型敌机的最大等级，与生命有关
    static private int middlePaineMaxLv = 50;//中型敌机的最大等级，与生命有关
    static private int bossPaineMaxLv = 50;//中型敌机的最大等级，与生命有关
    static private int myMaxLv = 20;//我方等级上限
    static private int mylife = 4;//我方战机数
    static private int skillSum = 0;//我方必杀技次数
    static private int skillSpeed = 100;//我方必杀子弹的速度
    static private int bossSkillSpeed = 40;//我方必杀子弹的速度
    static private int gameViewWidth;//游戏view，用来测量宽
    static private int gameViewHight;//游戏view，用来测量宽
    static private Skill skill;//我方必杀技实现类
    static private WindmillSkill windmillSkill;//风车旋转型必杀实现类
    static private BossSkill bossSkill;//Boss必杀技实现类
    static private int skillBulletMult = 5000;//必杀技与必杀技等级伤害的系数（倍数）
    static private int windMillBulletStartLv = 1;//风车旋转必杀技启动的等级
    static private int windMillBulletMult = 200;//风车旋转必杀技与必杀技等级伤害的系数（倍数）
    static private int smallGrow = 40;//生命成长系数（倍数）
    static private int middleGraw = 1000;//生命成长系数（倍数）
    static private int bigGraw = 2000;//生命成长系数（倍数）
    static private int bossGraw = 50000;//生命成长系数（倍数）
    static private BossPlane currentBossPlane;//当前boss，哪个Boss要用大招，就动态改变。
    static private long smallCd = 20;//复活冷却时间，帧数计算
    static private long middleCd = 100;//复活冷却时间，帧数计算
    static private long bigCd = 200;//复活冷却时间，帧数计算
    static private long bossCd = 1000;//复活冷却时间，帧数计算
    static private long goodsCd = 30;//该处是秒计算
    static private int smallMaxSum = 8;//创建的飞机数量
    static private int middleMaxSum = 4;
    static private int bigMaxSum = 2;
    static private int bossMaxSum = 1;
    static private int myPlaneBulletSize = 10;//我方战机弹夹长度
    static private int myBulletGrow = 20;//我方子弹伤害成长系数
    static private boolean invincible = false;//我方战机是否无敌
    static int smallEnemySpeed = 10;
    static int middleEnemySpeed = 15;
    static int bigEnemySpeed = 15;
    static int bossEnemySpeed = 20;
    static boolean isCustom;//是关卡模式
    private static int currentLv = 1;//关卡数
    private static long customScore = 300000;//关卡分数间隔
    private static long boss_sum_kill = 0;
    private static long big_sum_kill = 0;
    private static long middle_sum_kill = 0;
    private static long small_sum_kill = 0;

    public static long getBoss_sum_kill() {
        return boss_sum_kill;
    }

    public static long getBig_sum_kill() {
        return big_sum_kill;
    }

    public static long getMiddle_sum_kill() {
        return middle_sum_kill;
    }

    public static long getSmall_sum_kill() {
        return small_sum_kill;
    }

    public static void addBossKill() {
        boss_sum_kill++;
    }

    public static void addBigKill() {
        big_sum_kill++;
    }

    public static void addMiddleKill() {
        middle_sum_kill++;
    }

    public static void addSmallKill() {
        small_sum_kill++;
    }

    public static void setBoss_sum_kill(long boss_sum_kill) {
        DataUtils.boss_sum_kill = boss_sum_kill;
    }

    public static void setBig_sum_kill(long big_sum_kill) {
        DataUtils.big_sum_kill = big_sum_kill;
    }

    public static void setMiddle_sum_kill(long middle_sum_kill) {
        DataUtils.middle_sum_kill = middle_sum_kill;
    }

    public static void setSmall_sum_kill(long small_sum_kill) {
        DataUtils.small_sum_kill = small_sum_kill;
    }

    public static void checkCustoms() {
        if (isCustom)
            if (allScore > currentLv * customScore) {
                updata();
            }
    }

    private static void updata() {
        currentLv++;
        setSmallGrow(smallGrow * 6 / 5);
        setMiddleGraw(middleGraw * 6 / 5);
        setBigGraw(bigGraw * 6 / 5);
        setBossGraw(bossGraw * 6 / 5);
    }

    public static boolean isIsCustom() {
        return isCustom;
    }

    public static void setIsCustom(boolean isCustom) {
        DataUtils.isCustom = isCustom;
    }

    public static int getSmallEnemySpeed() {
        return smallEnemySpeed;
    }

    public static void setSmallEnemySpeed(int smallEnemySpeed) {
        DataUtils.smallEnemySpeed = smallEnemySpeed;
    }

    public static int getMiddleEnemySpeed() {
        return middleEnemySpeed;
    }

    public static void setMiddleEnemySpeed(int middleEnemySpeed) {
        DataUtils.middleEnemySpeed = middleEnemySpeed;
    }

    public static int getBigEnemySpeed() {
        return bigEnemySpeed;
    }

    public static void setBigEnemySpeed(int bigEnemySpeed) {
        DataUtils.bigEnemySpeed = bigEnemySpeed;
    }

    public static int getBossEnemySpeed() {
        return bossEnemySpeed;
    }

    public static void setBossEnemySpeed(int bossEnemySpeed) {
        DataUtils.bossEnemySpeed = bossEnemySpeed;
    }

    public static long getGoodsCd() {
        return goodsCd;
    }

    public static void setGoodsCd(long goodsCd) {
        DataUtils.goodsCd = goodsCd;
    }

    public static int getMyBulletGrow() {
        return myBulletGrow;
    }

    public static void setMyBulletGrow(int myBulletGrow) {
        DataUtils.myBulletGrow = myBulletGrow;
    }

    public static long getSmallCd() {
        return smallCd;
    }

    public static void setSmallCd(long smallCd) {
        DataUtils.smallCd = smallCd;
    }

    public static int getBossSkillSpeed() {
        return bossSkillSpeed;
    }

    public static void setBossSkillSpeed(int bossSkillSpeed) {
        DataUtils.bossSkillSpeed = bossSkillSpeed;
    }

    public static boolean isInvincible() {
        return invincible;
    }

    public static void setInvincible(boolean invincible) {
        DataUtils.invincible = invincible;
    }

    public static int getWindMillBulletStartLv() {
        return windMillBulletStartLv;
    }

    public static void setWindMillBulletStartLv(int windMillBulletStartLv) {
        DataUtils.windMillBulletStartLv = windMillBulletStartLv;
    }

    public static int getMyPlaneBulletSize() {
        return myPlaneBulletSize;
    }

    public static void setMyPlaneBulletSize(int myPlaneBulletSize) {
        DataUtils.myPlaneBulletSize = myPlaneBulletSize;
    }

    public static int getSmallMaxSum() {
        return smallMaxSum;
    }

    public static void setSmallMaxSum(int smallMaxSum) {
        DataUtils.smallMaxSum = smallMaxSum;
    }

    public static int getMiddleMaxSum() {
        return middleMaxSum;
    }

    public static void setMiddleMaxSum(int middleMaxSum) {
        DataUtils.middleMaxSum = middleMaxSum;
    }

    public static int getBigMaxSum() {
        return bigMaxSum;
    }

    public static void setBigMaxSum(int bigMaxSum) {
        DataUtils.bigMaxSum = bigMaxSum;
    }

    public static int getBossMaxSum() {
        return bossMaxSum;
    }

    public static void setBossMaxSum(int bossMaxSum) {
        DataUtils.bossMaxSum = bossMaxSum;
    }


    public static long getBossCd() {
        return bossCd;
    }

    public static void setBossCd(long bossCd) {
        DataUtils.bossCd = bossCd;
    }

    public static long getMiddleCd() {
        return middleCd;
    }

    public static void setMiddleCd(long middleCd) {
        DataUtils.middleCd = middleCd;
    }

    public static long getBigCd() {
        return bigCd;
    }

    public static void setBigCd(long bigCd) {
        DataUtils.bigCd = bigCd;
    }

    public static BossPlane getCurrentBossPlane() {
        return currentBossPlane;
    }

    public static void setCurrentBossPlane(BossPlane currentBossPlane) {
        DataUtils.currentBossPlane = currentBossPlane;
    }

    public static int getSmallGrow() {
        return smallGrow;
    }

    public static void setSmallGrow(int smallGrow) {
        DataUtils.smallGrow = smallGrow;
    }

    public static int getMiddleGraw() {
        return middleGraw;
    }

    public static void setMiddleGraw(int middleGraw) {
        DataUtils.middleGraw = middleGraw;
    }

    public static int getBigGraw() {
        return bigGraw;
    }

    public static void setBigGraw(int bigGraw) {
        DataUtils.bigGraw = bigGraw;
    }

    public static int getBossGraw() {
        return bossGraw;
    }

    public static void setBossGraw(int bossGraw) {
        DataUtils.bossGraw = bossGraw;
    }

    public static int getSkillBulletMult() {
        return skillBulletMult;
    }

    public static void setSkillBulletMult(int skillBulletMult) {
        DataUtils.skillBulletMult = skillBulletMult;
    }

    public static int getWindMillBulletMult() {
        return windMillBulletMult;
    }

    public static void setWindMillBulletMult(int windMillBulletMult) {
        DataUtils.windMillBulletMult = windMillBulletMult;
    }

    public static BossSkill getBossSkill(Resources resources) {
        if (bossSkill != null)
            return bossSkill;
        else return bossSkill = new BossSkill(resources);
    }

    public static void setBossSkill(BossSkill bossSkill) {
        DataUtils.bossSkill = bossSkill;
    }

    public static WindmillSkill getWindmillSkill(Resources resources) {
        if (windmillSkill != null)
            return windmillSkill;
        else return windmillSkill = new WindmillSkill(resources);
    }

    public static void setWindmillSkill(WindmillSkill windmillSkill) {
        DataUtils.windmillSkill = windmillSkill;
    }

    public static Skill getSkill(Resources resources) {
        if (skill != null)
            return skill;
        else return skill = new Skill(resources);
    }

    public static void setSkill(Skill skill) {
        DataUtils.skill = skill;
    }

    public static int getSkillSpeed() {
        return skillSpeed;
    }

    public static void setSkillSpeed(int skillSpeed) {
        DataUtils.skillSpeed = skillSpeed;
    }

    public static int getGameViewWidth() {
        return gameViewWidth;
    }

    public static void setGameViewWidth(int gameViewWidth) {
        DataUtils.gameViewWidth = gameViewWidth;
    }

    public static int getGameViewHight() {
        return gameViewHight;
    }

    public static void setGameViewHight(int gameViewHight) {
        DataUtils.gameViewHight = gameViewHight;
    }

    public static int getSkillSum() {
        return skillSum;
    }

    public static void setSkillSum(int skillSum) {
        DataUtils.skillSum = skillSum;
    }

    public static int getMylife() {
        return mylife;
    }

    public static int setMylife(int mylife) {
        return DataUtils.mylife = mylife;
    }

    public static long getSmallPlaneScore() {
        return smallPlaneScore;
    }

    public static void setSmallPlaneScore(long smallPlaneScore) {
        DataUtils.smallPlaneScore = smallPlaneScore;
    }

    public static long getMiddlePlaneScore() {
        return middlePlaneScore;
    }

    public static void setMiddlePlaneScore(long middlePlaneScore) {
        DataUtils.middlePlaneScore = middlePlaneScore;
    }

    public static long getBigPlaneScore() {
        return bigPlaneScore;
    }

    public static void setBigPlaneScore(long bigPlaneScore) {
        DataUtils.bigPlaneScore = bigPlaneScore;
    }

    public static long getBosPlaneScore() {
        return bosPlaneScore;
    }

    public static void setBosPlaneScore(long bosPlaneScore) {
        DataUtils.bosPlaneScore = bosPlaneScore;
    }

    public static synchronized void runEnemyBulletAttack() {
        executorService.execute(runnableEnemyBulletAttack);
    }

    private static Runnable runnableEnemyBulletAttack = new Runnable() {
        @Override
        public void run() {
            enemyBulletAttack();//敌方子弹攻击
        }
    };

    private static void enemyBulletAttack() {
        try {
            for (SmallPlane enemyPlane : smallPlanes) {
                ArrayList<EnemyBullet> enemyBullits = enemyPlane.getEnemyBullits();
                for (BaseObject enemyBullit : enemyBullits) {
                    attack(enemyBullit, mainPlane);
                }
            }
            for (MiddlePlane enemyPlane : middlePlanes) {
                ArrayList<EnemyBullet> enemyBullits = enemyPlane.getEnemyBullits();
                for (BaseObject enemyBullit : enemyBullits) {
                    attack(enemyBullit, mainPlane);
                }
            }
            for (BigPlane enemyPlane : bigPlanes) {
                ArrayList<EnemyBullet> enemyBullits = enemyPlane.getEnemyBullits();
                for (BaseObject enemyBullit : enemyBullits) {
                    attack(enemyBullit, mainPlane);
                }
            }
            for (BossPlane enemyPlane : bossPlanes) {
                ArrayList<EnemyBullet> enemyBullits = enemyPlane.getEnemyBullits();
                for (BaseObject enemyBullit : enemyBullits) {
                    attack(enemyBullit, mainPlane);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void attack(BaseObject enemyBullet, MainPlane mainPlane) {//敌方子弹与我方战机相遇
        if (mainPlane.isAlive() && enemyBullet.isAlive() && mainPlane.unbeatable <= 0 && Math.sqrt(Math.pow(enemyBullet.midx - mainPlane.midx, 2) + Math.pow(enemyBullet.midy - mainPlane.midy, 2)) < (enemyBullet.object_width + mainPlane.object_width) / 3) {
            //object_width和testPlant.object_width都是直径距离/2就是bitmap刚刚贴边除以三，是大概扣除一下透明部分的bitmap的部分，
            //击中testPlant了
            enemyBullet.setAlive(false);//子弹死亡
            if (mainPlane.getLv() > 1) {//最低1级，伤害是等级的倍数，所以不可以为0,也可以看着0生命值就是死亡
                mainPlane.setLv(mainPlane.getLv() - 1);
                mainPlane.unbeatable = 100;
            } else {
                mainPlane.setAlive(false);
            }
        }
    }

    public static void runSkillAttack() {
        executorService.execute(runnableskillAttack);
    }

    private static Runnable runnableskillAttack = new Runnable() {
        @Override
        public void run() {
            try {
                List<SkillBullet> skillBullets = skill.getSkillBullets();
                for (SkillBullet skillBullet : skillBullets) {
                    if (skillBullet.isAlive())
                        skillAttack(skillBullet);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };

    public static void skillAttack(SkillBullet skillBullet) {//敌方战机与我方必杀技相遇，调用该方法前已经确定技能子弹是活的??
        for (BaseObject enemyPlane : smallPlanes) {
            if (enemyPlane.isAlive() && Math.sqrt(Math.pow(enemyPlane.midx - skillBullet.midx, 2) + Math.pow(enemyPlane.midy - skillBullet.midy, 2)) < (enemyPlane.object_width + skillBullet.object_width) / 3) {
                //object_width和testPlant.object_width都是直径距离/2就是bitmap刚刚贴边除以三，是大概扣除一下透明部分的bitmap的部分，
                //击中testPlant了
                skillBullet.setAlive(false);//子弹死亡
                if (enemyPlane.getLife() > 0) {//最低1级，伤害是等级的倍数，所以不可以为0,也可以看着0生命值就是死亡
                    enemyPlane.setLife(enemyPlane.getLife() - skillBullet.getLv() * getSkillBulletMult());
                    if (enemyPlane.getLife() <= 0) {
                        enemyPlane.setAlive(false);
                    }
                }
            }
        }
        for (BaseObject enemyPlane : middlePlanes) {
            if (enemyPlane.isAlive() && enemyPlane.getCd() <= 0 && Math.sqrt(Math.pow(enemyPlane.midx - skillBullet.midx, 2) + Math.pow(enemyPlane.midy - skillBullet.midy, 2)) < (enemyPlane.object_width + skillBullet.object_width) / 3) {
                //object_width和testPlant.object_width都是直径距离/2就是bitmap刚刚贴边除以三，是大概扣除一下透明部分的bitmap的部分，
                //击中testPlant了
                skillBullet.setAlive(false);//子弹死亡
                if (enemyPlane.getLife() > 0) {//最低1级，伤害是等级的倍数，所以不可以为0,也可以看着0生命值就是死亡
                    enemyPlane.setLife(enemyPlane.getLife() - skillBullet.getLv() * getSkillBulletMult());
                    if (enemyPlane.getLife() <= 0) {
                        enemyPlane.setAlive(false);
                    }
                }
            }
        }
        for (BaseObject enemyPlane : bigPlanes) {
            if (enemyPlane.isAlive() && enemyPlane.getCd() <= 0 && Math.sqrt(Math.pow(enemyPlane.midx - skillBullet.midx, 2) + Math.pow(enemyPlane.midy - skillBullet.midy, 2)) < (enemyPlane.object_width + skillBullet.object_width) / 3) {
                //object_width和testPlant.object_width都是直径距离/2就是bitmap刚刚贴边除以三，是大概扣除一下透明部分的bitmap的部分，
                //击中testPlant了
                skillBullet.setAlive(false);//子弹死亡
                if (enemyPlane.getLife() > 0) {//最低1级，伤害是等级的倍数，所以不可以为0,也可以看着0生命值就是死亡
                    enemyPlane.setLife(enemyPlane.getLife() - skillBullet.getLv() * getSkillBulletMult());
                    if (enemyPlane.getLife() <= 0) {
                        enemyPlane.setAlive(false);
                    }
                }
            }
        }
        for (BaseObject enemyPlane : bossPlanes) {
            if (enemyPlane.isAlive() && enemyPlane.getCd() <= 0 && Math.sqrt(Math.pow(enemyPlane.midx - skillBullet.midx, 2) + Math.pow(enemyPlane.midy - skillBullet.midy, 2)) < (enemyPlane.object_width + skillBullet.object_width) / 3) {
                //object_width和testPlant.object_width都是直径距离/2就是bitmap刚刚贴边除以三，是大概扣除一下透明部分的bitmap的部分，
                //击中testPlant了
                skillBullet.setAlive(false);//子弹死亡
                if (enemyPlane.getLife() > 0) {//最低1级，伤害是等级的倍数，所以不可以为0,也可以看着0生命值就是死亡
                    enemyPlane.setLife(enemyPlane.getLife() - skillBullet.getLv() * getSkillBulletMult());
                    if (enemyPlane.getLife() <= 0) {
                        enemyPlane.setAlive(false);
                    }
                }
            }
        }
    }

    public static void WindmillAttack(WindmillBullet skillBullet) {//敌方战机与我方必杀技相遇，调用该方法前已经确定技能子弹是活的,WindmillBullet是穿透型的，不会因为击中目标二死亡
        for (BaseObject enemyPlane : smallPlanes) {
            if (enemyPlane.isAlive()&& enemyPlane.getCd() <= 0 && Math.sqrt(Math.pow(enemyPlane.midx - skillBullet.midx, 2) + Math.pow(enemyPlane.midy - skillBullet.midy, 2)) < (enemyPlane.object_width + skillBullet.object_width) / 3) {
                //object_width和testPlant.object_width都是直径距离/2就是bitmap刚刚贴边除以三，是大概扣除一下透明部分的bitmap的部分，
                //击中testPlant了
                if (enemyPlane.getLife() > 0) {//最低1级，伤害是等级的倍数，所以不可以为0,也可以看着0生命值就是死亡
                    enemyPlane.setLife(enemyPlane.getLife() - skillBullet.getLv() * getWindMillBulletMult());
                    if (enemyPlane.getLife() <= 0) {
                        enemyPlane.setAlive(false);
                    }
                }
            }
        }
        for (BaseObject enemyPlane : middlePlanes) {//中型飞机以上都有CD
            if (enemyPlane.isAlive() && enemyPlane.getCd() <= 0 && Math.sqrt(Math.pow(enemyPlane.midx - skillBullet.midx, 2) + Math.pow(enemyPlane.midy - skillBullet.midy, 2)) < (enemyPlane.object_width + skillBullet.object_width) / 3) {
                //object_width和testPlant.object_width都是直径距离/2就是bitmap刚刚贴边除以三，是大概扣除一下透明部分的bitmap的部分，
                //击中testPlant了
                if (enemyPlane.getLife() > 0) {//最低1级，伤害是等级的倍数，所以不可以为0,也可以看着0生命值就是死亡
                    enemyPlane.setLife(enemyPlane.getLife() - skillBullet.getLv() * getWindMillBulletMult());
                    if (enemyPlane.getLife() <= 0) {
                        enemyPlane.setAlive(false);
                    }
                }
            }
        }
        for (BaseObject enemyPlane : bigPlanes) {
            if (enemyPlane.isAlive() && enemyPlane.getCd() <= 0 && Math.sqrt(Math.pow(enemyPlane.midx - skillBullet.midx, 2) + Math.pow(enemyPlane.midy - skillBullet.midy, 2)) < (enemyPlane.object_width + skillBullet.object_width) / 3) {
                //object_width和testPlant.object_width都是直径距离/2就是bitmap刚刚贴边除以三，是大概扣除一下透明部分的bitmap的部分，
                //击中testPlant了
                if (enemyPlane.getLife() > 0) {//最低1级，伤害是等级的倍数，所以不可以为0,也可以看着0生命值就是死亡
                    enemyPlane.setLife(enemyPlane.getLife() - skillBullet.getLv() * getWindMillBulletMult());
                    if (enemyPlane.getLife() <= 0) {
                        enemyPlane.setAlive(false);
                    }
                }
            }
        }
        for (BaseObject enemyPlane : bossPlanes) {
            if (enemyPlane.isAlive() && enemyPlane.getCd() <= 0 && Math.sqrt(Math.pow(enemyPlane.midx - skillBullet.midx, 2) + Math.pow(enemyPlane.midy - skillBullet.midy, 2)) < (enemyPlane.object_width + skillBullet.object_width) / 3) {
                //object_width和testPlant.object_width都是直径距离/2就是bitmap刚刚贴边除以三，是大概扣除一下透明部分的bitmap的部分，
                //击中testPlant了
                if (enemyPlane.getLife() > 0) {//最低1级，伤害是等级的倍数，所以不可以为0,也可以看着0生命值就是死亡
                    enemyPlane.setLife(enemyPlane.getLife() - skillBullet.getLv() * getWindMillBulletMult());
                    if (enemyPlane.getLife() <= 0) {
                        enemyPlane.setAlive(false);
                    }
                }
            }
        }
    }

    public static void runbossSkillAttack() {
        executorService.execute(runnablebossSkillAttack);
    }

    static Runnable runnablebossSkillAttack = new Runnable() {
        @Override
        public void run() {
            try {
                List<BossSkillBullet> skillBullets = bossSkill.getSkillBullets();
                for (BossSkillBullet bossSkillBullet : skillBullets) {
                    bossSkillAttack(bossSkillBullet);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };

    public static void bossSkillAttack(BossSkillBullet skillBullet) {//敌方战机与我方必杀技相遇，调用该方法前已经确定技能子弹是活的
        if (mainPlane.isAlive() && skillBullet.isAlive() && mainPlane.unbeatable <= 0 && Math.sqrt(Math.pow(mainPlane.midx - skillBullet.midx, 2) + Math.pow(mainPlane.midy - skillBullet.midy, 2)) < (mainPlane.object_width + skillBullet.object_width) / 3) {
            //object_width和testPlant.object_width都是直径距离/2就是bitmap刚刚贴边除以三，是大概扣除一下透明部分的bitmap的部分，
            //击中testPlant了
            skillBullet.setAlive(false);//子弹死亡
            if (mainPlane.getLv() > 1) {
                //最低1级，伤害是等级的倍数，所以不可以为0,也可以看着0生命值就是死亡
                mainPlane.setLv(mainPlane.getLv() - 1);
                mainPlane.unbeatable = 100;
            } else {
                mainPlane.setAlive(false);
            }
        }

    }

    public static int getMyMaxLv() {
        return myMaxLv;
    }

    public static void setMyMaxLv(int myMaxLv) {
        DataUtils.myMaxLv = myMaxLv;
    }

    public static int getSmallPaineMaxLv() {
        return smallPaineMaxLv;
    }

    public static void setSmallPaineMaxLv(int smallPaineMaxLv) {
        DataUtils.smallPaineMaxLv = smallPaineMaxLv;
    }

    public static int getMiddlePaineMaxLv() {
        return middlePaineMaxLv;
    }

    public static void setMiddlePaineMaxLv(int middlePaineMaxLv) {
        DataUtils.middlePaineMaxLv = middlePaineMaxLv;
    }

    public static int getBossPaineMaxLv() {
        return bossPaineMaxLv;
    }

    public static void setBossPaineMaxLv(int bossPaineMaxLv) {
        DataUtils.bossPaineMaxLv = bossPaineMaxLv;
    }

    public static long getStopTime() {
        long time = start - stop;
        start = 0;
        stop = 0;
        return time;
    }

    public static Paint getPaint() {
        if (paint == null) {
            paint = new Paint();
            paint.setTextSize(40);
//            paint.setStyle(Paint.Style.STROKE);
            paint.setColor(Color.rgb(235, 161, 1));
            return paint;
        } else
            return paint;
    }

    public static void setPaint(Paint paint) {
        DataUtils.paint = paint;
    }

    public static ExecutorService getExecutorService() {
        if (executorService == null)
            return executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());//用线程池，不要频繁创建线程，否则app会崩。这里我使用CPU核心数相同大小的线程池
        else return executorService;
    }

    public static void setExecutorService(ExecutorService executorService) {
        DataUtils.executorService = executorService;
    }

    public static MainPlane getmainPlane(Resources resources) {
        if (mainPlane == null) {
            mainPlane = new MainPlane(resources, getPaint());
            mainPlane.setScreenWH(gameViewWidth, gameViewHight);//设定初始位置
            return mainPlane;
        } else
            return mainPlane;
    }

    public void setmainPlane(MainPlane mainPlane) {
        this.mainPlane = mainPlane;
    }

    public static Bitmap getLifeIcon(Resources resources) {
        if (lifeIcon != null && !lifeIcon.isRecycled())
            return lifeIcon;
        else
            return lifeIcon = BitmapFactory.decodeResource(resources, R.drawable.life_amount);
    }

    public static void setLifeIcon(Bitmap lifeIcon) {
        DataUtils.lifeIcon = lifeIcon;
    }

    public static Bitmap getBackground2(Resources resources) {
        if (background2 != null && !background2.isRecycled())
            return background2;
        else
            return background2 = BitmapFactory.decodeResource(resources, R.drawable.bg_02);
    }

    public void setBackground2(Bitmap background2) {
        this.background2 = background2;
    }

    public static Bitmap getBackground(Resources resources) {
        if (background != null && !background.isRecycled())
            return background;
        else
            return background = BitmapFactory.decodeResource(resources, R.drawable.bg_01);
    }

    public void setBackground(Bitmap background) {
        this.background = background;
    }

    public static float getScalex() {
        return scalex;
    }

    public static void setScalex(float scalex) {
        DataUtils.scalex = scalex;
    }

    public static float getScaley() {
        return scaley;
    }

    public static void setScaley(float scaley) {
        DataUtils.scaley = scaley;
    }

    public static float getBg_y() {
        return bg_y;
    }

    public static void setBg_y(float bg_y) {
        DataUtils.bg_y = bg_y;
    }

    public static float getBg_y2() {
        return bg_y2;
    }

    public static void setBg_y2(float bg_y2) {
        DataUtils.bg_y2 = bg_y2;
    }

    public static boolean isIsPlaying() {
        return isPlaying;
    }

    public static void setIsPlaying(boolean isPlaying) {
        DataUtils.isPlaying = isPlaying;
        if (isPlaying) {
            start = System.currentTimeMillis();
            long stopTime = getStopTime();
            bulletBuffsTime += stopTime;

        } else stop = System.currentTimeMillis();

    }

    public static List<SmallPlane> getSmallPlanes() {
        if (smallPlanes != null)
            return smallPlanes;
        else return smallPlanes = new ArrayList<>();
    }

    public void setSmallPlanes(List<SmallPlane> smallPlanes) {
        this.smallPlanes = smallPlanes;
    }

    public static List<BossPlane> getBossPlanes() {
        if (bossPlanes != null)
            return bossPlanes;
        else
            return bossPlanes = new ArrayList<>();
    }

    public static void setBossPlanes(List<BossPlane> bossPlanes) {
        DataUtils.bossPlanes = bossPlanes;
    }

    public static List<MiddlePlane> getMiddlePlanes() {
        if (middlePlanes != null)
            return middlePlanes;
        else return middlePlanes = new ArrayList<>();
    }

    public void setMiddlePlanes(List<MiddlePlane> middlePlanes) {
        this.middlePlanes = middlePlanes;
    }

    public static List<BigPlane> getBigPlanes() {
        if (bigPlanes != null)
            return bigPlanes;
        else return bigPlanes = new ArrayList<>();
    }

    public static void setBigPlanes(List<BigPlane> bigPlanes) {
        DataUtils.bigPlanes = bigPlanes;
    }

    public static ArrayList<BulletBuff> getBulletBuffs() {
        if (bulletBuffs != null)
            return bulletBuffs;
        else return bulletBuffs = new ArrayList<>();
    }

    public void setBulletBuffs(ArrayList<BulletBuff> bulletBuffs) {
        this.bulletBuffs = bulletBuffs;
    }

    public static long getBulletBuffsTime() {
        if (bulletBuffsTime == 0) {
            return bulletBuffsTime = System.currentTimeMillis();
        } else
            return bulletBuffsTime;
    }

    public static void setBulletBuffsTime(long bulletBuffsTime) {
        DataUtils.bulletBuffsTime = bulletBuffsTime;
    }

    public static long getAllScore() {
        return allScore;
    }

    public static synchronized void setAllScore(BaseObject baseObject) {
        DataUtils.allScore += baseObject.getScore();
    }

    public static Bitmap getMissile(Resources resources) {

        if (missile != null && !missile.isRecycled())
            return missile;
        else return missile = BitmapFactory.decodeResource(resources, R.drawable.missile_bt);
    }

    public static void setMissile(Bitmap missile) {
        DataUtils.missile = missile;
    }

    public static Bitmap getPlayButton(Resources resources) {
        if (playButton != null && !playButton.isRecycled())
            return playButton;
        else return playButton = BitmapFactory.decodeResource(resources,
                R.drawable.play);
    }

    public static void setPlayButton(Bitmap playButton) {
        DataUtils.playButton = playButton;
    }

    public static MediaPlayer getmMediaPlayer() {
        return mMediaPlayer;
    }

    public static void setmMediaPlayer(MediaPlayer mMediaPlayer) {
        DataUtils.mMediaPlayer = mMediaPlayer;
    }

    public static void runWindmillArrack() {
        executorService.execute(runnableWindmillArrack);
    }

    private static Runnable runnableWindmillArrack = new Runnable() {
        @Override
        public void run() {
            windmillArrack();
        }
    };

    private static void windmillArrack() {
        try {
            ArrayList<WindmillBullet> windmillBullets = windmillSkill.getWindmillBullets();
            for (WindmillBullet windmillBullet : windmillBullets) {
                WindmillAttack(windmillBullet);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static synchronized void runAttack() {
        executorService.execute(runnableAttack);
    }

    private static Runnable runnableAttack = new Runnable() {
        @Override
        public void run() {
            attack();//我方子弹与敌方战机相遇，和我方战机与地方战机碰撞
        }
    };

    public static void attack() {
        try {
            //获取子弹
            ArrayList<Bullet> bullets = mainPlane.getBullets();
            for (SmallPlane enemy : smallPlanes) {
                if (enemy.getCd() <= 0) {
                    for (Bullet bullet : bullets) {
                        if (bullet instanceof DoubleBullet) {
//                            enemy.doubleBulletAttack((DoubleBullet) bullet);
                            doubleBulletAttack((DoubleBullet) bullet, enemy);
                        } else {
//                            enemy.bulletAttack(bullet);
                            bulletAttack(bullet, enemy);
                        }

                    }
                    if (mainPlane.isAlive() && mainPlane.unbeatable <= 0 && mainPlane.leftx < enemy.rightx && mainPlane.rightx > enemy.leftx && mainPlane.lefty < enemy.righty && mainPlane.righty > enemy.righty) {
                        if (mainPlane.getLv() > 1) {//最低1级，伤害是等级的倍数，所以不可以为0
                            mainPlane.setLv(mainPlane.getLv() - 1);
                            mainPlane.unbeatable = 100;
                        } else {
                            mainPlane.setAlive(false);
                        }
                    }
                }
            }
            for (MiddlePlane enemy : middlePlanes) {
                if (enemy.getCd() <= 0) {
                    for (Bullet bullet : bullets) {
                        if (bullet instanceof DoubleBullet) {
//                            enemy.doubleBulletAttack((DoubleBullet) bullet);
                            doubleBulletAttack((DoubleBullet) bullet, enemy);
                        } else {
//                            enemy.bulletAttack(bullet);
                            bulletAttack(bullet, enemy);
                        }
                    }
                    if (mainPlane.isAlive() && mainPlane.unbeatable <= 0 && mainPlane.leftx < enemy.rightx && mainPlane.rightx > enemy.leftx && mainPlane.lefty < enemy.righty && mainPlane.righty > enemy.righty) {
                        if (mainPlane.getLv() > 1) {//最低1级，伤害是等级的倍数，所以不可以为0
                            mainPlane.setLv(mainPlane.getLv() - 1);
                            mainPlane.unbeatable = 100;
                        } else {
                            mainPlane.setAlive(false);
                        }
                    }
                }
            }
            for (BigPlane enemy : bigPlanes) {
                if (enemy.getCd() <= 0) {
                    for (Bullet bullet : bullets) {
                        if (bullet instanceof DoubleBullet) {
//                            enemy.doubleBulletAttack((DoubleBullet) bullet);
                            doubleBulletAttack((DoubleBullet) bullet, enemy);
                        } else {
//                            enemy.bulletAttack(bullet);
                            bulletAttack(bullet, enemy);
                        }
                    }
                    if (mainPlane.isAlive() && mainPlane.unbeatable <= 0 && mainPlane.leftx < enemy.rightx && mainPlane.rightx > enemy.leftx && mainPlane.lefty < enemy.righty && mainPlane.righty > enemy.righty) {
                        if (mainPlane.getLv() > 1) {//最低1级，伤害是等级的倍数，所以不可以为0
                            mainPlane.setLv(mainPlane.getLv() - 1);
                            mainPlane.unbeatable = 100;
                        } else {
                            mainPlane.setAlive(false);
                        }
                    }
                }
            }
            for (BossPlane enemy : bossPlanes) {
                if (enemy.getCd() <= 0) {
                    for (Bullet bullet : bullets) {
                        if (bullet instanceof DoubleBullet) {
//                            enemy.doubleBulletAttack((DoubleBullet) bullet);
                            doubleBulletAttack((DoubleBullet) bullet, enemy);
                        } else {
//                            enemy.bulletAttack(bullet);
                            bulletAttack(bullet, enemy);
                        }
                    }
                    if (mainPlane.isAlive() && mainPlane.unbeatable <= 0 && mainPlane.leftx < enemy.rightx && mainPlane.rightx > enemy.leftx && mainPlane.lefty < enemy.righty && mainPlane.righty > enemy.righty) {
                        if (mainPlane.getLv() > 1) {//最低1级，伤害是等级的倍数，所以不可以为0
                            mainPlane.setLv(mainPlane.getLv() - 1);
                            mainPlane.unbeatable = 100;
                        } else {
                            mainPlane.setAlive(false);
                        }
                    }
                }
            }
        } catch (Exception e) {
            Log.e("AACC", "Exception: DataUtils:attack:" + e.toString());
            e.printStackTrace();
        }
    }

    //普通子弹的攻击
    private static void bulletAttack(Bullet bullet, BaseObject enemyPlane) {
        if (bullet.isAlive() && bullet.leftx < enemyPlane.rightx && bullet.rightx > enemyPlane.leftx && bullet.lefty < enemyPlane.righty && bullet.righty > enemyPlane.righty) {
//                bullet.setAlive(false);//这一句如果添加子这里而不是下面，则敌机在爆炸的时候依然阻碍子弹穿越。
            if (enemyPlane.life > 0) {//战机生命对于0
                enemyPlane.life = enemyPlane.life - bullet.getLv() * myBulletGrow;//子弹的伤害当作子弹等级的倍计算；
                bullet.setAlive(false);//子弹攻击之后，生命结束
                if (enemyPlane.life <= 0) {
                    enemyPlane.setAlive(false); //如果生命值小于0,战机生命完结
                }
            }
        }
    }

    private static void doubleBulletAttack(DoubleBullet doubleBullet, BaseObject enemyPlane) {
        if (doubleBullet.isAlive()) {
            //先判断左边的子弹
            if (doubleBullet.isLeftIsAlive() && doubleBullet.leftx < enemyPlane.rightx && doubleBullet.rightx > enemyPlane.leftx && doubleBullet.lefty < enemyPlane.righty && doubleBullet.righty > enemyPlane.righty) {
//                bullet.setLeftIsAlive(false);//这一句如果添加子这里而不是下面，则敌机在爆炸的时候依然阻碍子弹穿越。
                if (enemyPlane.life > 0) {//战机生命对于0
                    enemyPlane.life = enemyPlane.life - doubleBullet.getLv() * myBulletGrow;//子弹的伤害当作子弹等级的倍计算；
                    doubleBullet.setLeftIsAlive(false);//子弹攻击之后，生命结束
                    if (enemyPlane.life <= 0) {
                        enemyPlane.setAlive(false); //如果生命值小于0,战机生命完结
                    }
                }
            }
            //在判断左边子弹
            if (doubleBullet.isRightIsAlive() && doubleBullet.leftx2 < enemyPlane.rightx && doubleBullet.rightx2 > enemyPlane.leftx && doubleBullet.lefty2 < enemyPlane.righty && doubleBullet.righty2 > enemyPlane.righty) {
//                bullet.setRightIsAlive(false);//这一句如果添加子这里而不是下面，则敌机在爆炸的时候依然阻碍子弹穿越。
                if (enemyPlane.life > 0) {//战机生命对于0
                    enemyPlane.life = enemyPlane.life - doubleBullet.getLv() * myBulletGrow;//子弹的伤害当作子弹等级的倍计算；
                    doubleBullet.setRightIsAlive(false);//子弹攻击之后，生命结束
                    if (enemyPlane.life <= 0) {
                        enemyPlane.setAlive(false); //如果生命值小于0,战机生命完结
                    }
                }
            }
        }
    }

    public static void runGetBuff() {
        executorService.execute(runnableGetBuff);
    }

    static private Runnable runnableGetBuff = new Runnable() {
        @Override
        public void run() {
            isGetBuff();
        }
    };

    private static void isGetBuff() {
        try {
            for (BulletBuff bulletBuff : bulletBuffs) {
                if (mainPlane.isAlive() && bulletBuff.isAlive() && bulletBuff.leftx < mainPlane.rightx && bulletBuff.rightx > mainPlane.leftx && mainPlane.lefty < bulletBuff.righty && mainPlane.righty > bulletBuff.lefty) {
                    bulletBuff.setAlive(false);
                    MainActivity.palySound(6, 0);
                    if (mainPlane.getLv() > DataUtils.getMyMaxLv()) {
                        mainPlane.setLv(DataUtils.getMyMaxLv());
                    } else {
                        mainPlane.setLv(mainPlane.getLv() + 1);
                    }
                    mainPlane.unbeatable += 40;//获得状态，战机无敌一小会
                    bulletBuff.setSeat(gameViewWidth / 2, 0);
                }
            }
        } catch (Exception e) {
            Log.e("AACC", "Exception:isGetBuff"+e );
            e.printStackTrace();
        }

    }

    static PlayButtonCallBack bgPlayButtonCallBack;
    static PlayButtonCallBack mainPlayButtonCallBack;
    static PlayButtonCallBack smallPlayButtonCallBack;
    static PlayButtonCallBack middlePlayButtonCallBack;
    static PlayButtonCallBack bigPlayButtonCallBack;
    static PlayButtonCallBack bossPlayButtonCallBack;

    public static PlayButtonCallBack getBgPlayButtonCallBack() {
        return bgPlayButtonCallBack;
    }

    public static void setBgPlayButtonCallBack(PlayButtonCallBack bgPlayButtonCallBack) {
        DataUtils.bgPlayButtonCallBack = bgPlayButtonCallBack;
    }

    public static PlayButtonCallBack getMainPlayButtonCallBack() {
        return mainPlayButtonCallBack;
    }

    public static void setMainPlayButtonCallBack(PlayButtonCallBack mainPlayButtonCallBack) {
        DataUtils.mainPlayButtonCallBack = mainPlayButtonCallBack;
    }

    public static PlayButtonCallBack getSmallPlayButtonCallBack() {
        return smallPlayButtonCallBack;
    }

    public static void setSmallPlayButtonCallBack(PlayButtonCallBack smallPlayButtonCallBack) {
        DataUtils.smallPlayButtonCallBack = smallPlayButtonCallBack;
    }

    public static PlayButtonCallBack getMiddlePlayButtonCallBack() {
        return middlePlayButtonCallBack;
    }

    public static void setMiddlePlayButtonCallBack(PlayButtonCallBack middlePlayButtonCallBack) {
        DataUtils.middlePlayButtonCallBack = middlePlayButtonCallBack;
    }

    public static PlayButtonCallBack getBigPlayButtonCallBack() {
        return bigPlayButtonCallBack;
    }

    public static void setBigPlayButtonCallBack(PlayButtonCallBack bigPlayButtonCallBack) {
        DataUtils.bigPlayButtonCallBack = bigPlayButtonCallBack;
    }

    public static PlayButtonCallBack getBossPlayButtonCallBack() {
        return bossPlayButtonCallBack;
    }

    public static void setBossPlayButtonCallBack(PlayButtonCallBack bossPlayButtonCallBack) {
        DataUtils.bossPlayButtonCallBack = bossPlayButtonCallBack;
    }

    public static void playButtonClick() {
        if (bgPlayButtonCallBack != null) {
            bgPlayButtonCallBack.playButtonOncleck();
        }
        if (mainPlayButtonCallBack != null) {
            mainPlayButtonCallBack.playButtonOncleck();
        }
        if (smallPlayButtonCallBack != null) {
            smallPlayButtonCallBack.playButtonOncleck();
        }
        if (middlePlayButtonCallBack != null) {
            middlePlayButtonCallBack.playButtonOncleck();
        }
        if (bigPlayButtonCallBack != null) {
            bigPlayButtonCallBack.playButtonOncleck();
        }
        if (bossPlayButtonCallBack != null) {
            bossPlayButtonCallBack.playButtonOncleck();
        }
    }

    public static void cleanData() {
        List<SmallPlane> smallPlanes = getSmallPlanes();
        while (smallPlanes.size() > 0) {
            smallPlanes.get(0).dataDestroyed();
            smallPlanes.remove(0);
        }
        List<MiddlePlane> middlePlanes = getMiddlePlanes();
        while (middlePlanes.size() > 0) {
            middlePlanes.get(0).dataDestroyed();
            middlePlanes.remove(0);
        }
        List<BigPlane> bigPlanes = getBigPlanes();
        while (bigPlanes.size() > 0) {
            bigPlanes.get(0).dataDestroyed();
            bigPlanes.remove(0);
        }

        List<BossPlane> bossPlanes = getBossPlanes();
        while (bossPlanes.size() > 0) {
            bossPlanes.get(0).dataDestroyed();
            bossPlanes.remove(0);
        }
        if (mainPlane != null) {
            mainPlane.dataDestroyed();
            mainPlane = null;
        }
        if (skill != null) {
            skill.dataDestroyed();
            skill = null;
        }
        if (bossSkill != null) {
            bossSkill.dataDestroyed();
            bossSkill = null;
        }
        if (windmillSkill != null) {
            windmillSkill.dataDestroyed();
            windmillSkill = null;
        }
        boss_sum_kill = 0;
        big_sum_kill = 0;
        middle_sum_kill = 0;
        small_sum_kill = 0;
        allScore = 0;
    }

    public interface PlayButtonCallBack {
        public void playButtonOncleck();
    }
}
